package com.ustc.hewei.nettyrpc2_0.common.codec;

import com.ustc.hewei.nettyrpc2_0.common.enumeration.PackageType;
import com.ustc.hewei.nettyrpc2_0.common.enumeration.RpcError;
import com.ustc.hewei.nettyrpc2_0.common.exception.RpcException;
import com.ustc.hewei.nettyrpc2_0.common.serializer.CommonSerializer;
import com.ustc.hewei.nettyrpc2_0.common.serializer.impl.fastJson.FastJsonSerializer;
import com.ustc.hewei.nettyrpc2_0.common.serializer.impl.kryo.KryoSerializer;
import com.ustc.hewei.nettyrpc2_0.common.serializer.impl.protostuff.ProtostuffSerializer;
import com.ustc.hewei.nettyrpc2_0.common.warp.RpcRequest;
import com.ustc.hewei.nettyrpc2_0.common.warp.RpcResponse;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @description: netty编码器
* @author hewei
* @date 2022/9/5 20:00
* @version 1.0
*/

public class CommonEncode extends MessageToByteEncoder {
    private final int MAGIC_NUMBER = 0xCAFEBABE;
    private final Logger logger = LoggerFactory.getLogger(CommonEncode.class);
    private final CommonSerializer serializer;

    public CommonEncode(CommonSerializer serializer) {
        this.serializer = serializer;
    }

    public CommonEncode() {
        this.serializer = new KryoSerializer();
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
        out.writeInt(MAGIC_NUMBER);
        if (msg instanceof RpcRequest) {
            out.writeInt(PackageType.REQUEST.getCode());
        } else if (msg instanceof RpcResponse) {
            out.writeInt(PackageType.RESPONSE.getCode());
        } else {
            logger.error("未知的包的类型 {}", msg.getClass());
            throw new RpcException(RpcError.UNKNOWN_PACKAGE, "在编码时遇到未知的包的类型");
        }
        out.writeInt(serializer.getCode());
        byte[] data = this.serializer.serializer(msg);
        out.writeInt(data.length);
        out.writeBytes(data);
    }
}
